package com.ruoyi.business.service.impl;

import com.ruoyi.business.domain.*;
import com.ruoyi.business.mapper.*;
import com.ruoyi.business.service.ImanagerService;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.domain.entity.SysDictType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.system.service.ISysDictTypeService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class ManagerServiceImpl  extends BaseServiceImpl implements ImanagerService {

    @Autowired
    private AchievementAwardsMapper achievementAwardsMapper;
    @Autowired
    private AnnualPlanWorkMapper annualPlanWorkMapper;
    @Autowired
    private TaskInfoMapper taskInfoMapper;
    @Autowired
    private TrainingRecordMapper trainingRecordMapper;
    @Autowired
    private WorkTicketInfoMapper workTicketInfoMapper;
    @Autowired
    private IndicatorMapper indicatorMapper;
    @Autowired
    private IndicatorDetailMapper indicatorDetailMapper;
    @Autowired
    private KnowledgeMapMapper knowledgeMapMapper;
    @Autowired
    private EmployeePerformanceMapper employeePerformanceMapper;
    @Autowired
    private EmployeeInfoMapper employeeInfoMapper;
    @Autowired
    private AnnualWorkDaysMapper annualWorkDaysMapper;
    @Autowired
    private EmployeeAwardsInfoMapper employeeAwardsInfoMapper;
    @Autowired
    private EmployeeTrainingMapper employeeTrainingMapper;
    @Autowired
    private PapersAndBooksMapper papersAndBooksMapper;
    @Autowired
    private EmployeeScoreMapper employeeScoreMapper;
    @Autowired
    private EmployeeClassificationTrainingSuggestionsMapper employeeClassificationTrainingSuggestionsMapper;

    @Autowired
    private IndicatorOneMapper indicatorOneMapper;

    @Autowired
    private IndicatorTowMapper indicatorTowMapper;

    @Autowired
    private IndicatorThreeMapper indicatorThreeMapper;

    @Autowired
    private IndicatorFourMapper indicatorFourMapper;

    @Autowired
    private IndicatorFiveMapper indicatorFiveMapper;

    @Autowired
    private IndicatorSixMapper indicatorSixMapper;


    @Autowired
    private ISysDictDataService dictDataService;

    @Autowired
    private ISysDictTypeService dictTypeService;

    private static final Logger logger = LoggerFactory.getLogger(ManagerServiceImpl.class);
    @Override
    public void clear() {
        try {
            achievementAwardsMapper.clearTable();
            annualPlanWorkMapper.clearTable();
            taskInfoMapper.clearTable();
            trainingRecordMapper.clearTable();
            workTicketInfoMapper.clearTable();
            indicatorDetailMapper.clearTable();
            knowledgeMapMapper.clearTable();
            employeePerformanceMapper.clearTable();
            employeeInfoMapper.clearTable();
            annualWorkDaysMapper.clearTable();
            employeeAwardsInfoMapper.clearTable();
            employeeTrainingMapper.clearTable();
            papersAndBooksMapper.clearTable();
            employeeScoreMapper.clearTable();
        } catch (Exception e) {
            logger.error("Failed to clear tables", e);
            throw new RuntimeException("Failed to clear tables", e);
        }
    }

    /**
     *重跑今年的数据
     *
     */
    @Override
    public void reRun(Date awd) {
        if (awd == null) {
            throw new IllegalArgumentException("Award year cannot be null");
        }

        indicatorDetailMapper.clearTableCurrent();

        employeeScoreMapper.clearTableCurrent();

        try {
            List<EmployeeInfo> userlist = employeeInfoMapper.selectEmployeeInfoList(new EmployeeInfo());
            if (userlist == null) {
                logger.warn("No employees found");
                return;
            }

            List<Indicator> indicatorList = indicatorMapper.selectIndicatorList(new Indicator());
            if (indicatorList == null) {
                logger.warn("No indicators found");
                return;
            }

            for (EmployeeInfo employeeInfo : userlist) {
                EmployeeScore employeeScore = new EmployeeScore();
                employeeScore.setEmployeeId(employeeInfo.getEmployeeId());
                employeeScore.setJobCategory(employeeInfo.getPositionCategoryMinor());
                employeeScore.setAwardYear(awd);

                employeeScore.setTitleLevelScore(BigDecimal.ZERO);
                employeeScore.setQualificationScore(BigDecimal.ZERO);
                employeeScore.setAwardScore(BigDecimal.ZERO);
                employeeScore.setTrainingContributionScore(BigDecimal.ZERO);
                employeeScore.setTrainingParticipationScore(BigDecimal.ZERO);
                employeeScore.setWorkPracticeScore(BigDecimal.ZERO);
                employeeScore.setGoalTaskScore(BigDecimal.ZERO);
                employeeScore.setPaperScore(BigDecimal.ZERO);
                employeeScore.setAnnualWorkingDaysScore(BigDecimal.ZERO);
                employeeScore.setKeyTaskScore(BigDecimal.ZERO);
                employeeScore.setJobExperienceScore(BigDecimal.ZERO);
                employeeScore.setPerformanceScore(BigDecimal.ZERO);
                employeeScore.setInnovationScore(BigDecimal.ZERO);


                for (Indicator indicator : indicatorList) {

                    try{

                        IndicatorDetail indicatorDetail = new IndicatorDetail();
                        indicatorDetail.setEmployeeId(employeeInfo.getEmployeeId());
                        indicatorDetail.setIndicatorType(indicator.getEvaluationMetric());
                        indicatorDetail.setIndicatorName(dictDataService.selectDictDataById(Long.parseLong(indicator.getEvaluationMetric())).getDictLabel());
                        indicatorDetail.setAwardYear(awd);
                        indicatorDetail.setCreateTime(new Date());

                        switch (indicator.getEvaluationMetric()) {
                            case "106":
                                employeeScore.setTitleLevelScore(BigDecimal.valueOf(getTitleLevelScore(employeeInfo.getProfessionalQualificationLevel(), indicator.getEvaluationMetric())));
                                indicatorDetail.setIndicatorScore(employeeScore.getTitleLevelScore());
                                break;
                            case "107":
                                employeeScore.setQualificationScore(BigDecimal.valueOf(getQualificationScore(employeeInfo.getSkillLevel(), indicator.getEvaluationMetric())));
                                indicatorDetail.setIndicatorScore(employeeScore.getQualificationScore());
                                break;
                            case "108":
                                employeeScore.setAwardScore(BigDecimal.valueOf(getAwardScore(employeeInfo.getEmployeeId(), indicator.getEvaluationMetric(), awd)));
                                indicatorDetail.setIndicatorScore(employeeScore.getAwardScore());
                                break;
                            case "109":
                                employeeScore.setTrainingContributionScore(BigDecimal.valueOf(getTrainingContributionScore(employeeInfo.getEmployeeId(), indicator.getEvaluationMetric(), awd)));
                                indicatorDetail.setIndicatorScore(employeeScore.getTrainingContributionScore());
                                break;
                            case "110":
                                employeeScore.setTrainingParticipationScore(BigDecimal.valueOf(getTrainingParticipationScore(employeeInfo.getEmployeeId(), indicator.getEvaluationMetric(), awd)));
                                indicatorDetail.setIndicatorScore(employeeScore.getTrainingParticipationScore());
                                break;
                            case "111":
                                employeeScore.setWorkPracticeScore(BigDecimal.valueOf(getWorkPracticeScore(employeeInfo.getEmployeeId(), indicator.getEvaluationMetric(), awd)));
                                indicatorDetail.setIndicatorScore(employeeScore.getWorkPracticeScore());
                                break;
                            case "112":
                                employeeScore.setJobExperienceScore(BigDecimal.valueOf(getJobExperienceScore(employeeInfo, indicator.getEvaluationMetric(), awd)));
                                indicatorDetail.setIndicatorScore(employeeScore.getJobExperienceScore());
                                break;
                            case "113":
                                employeeScore.setKeyTaskScore(BigDecimal.valueOf(getKeyTaskScore(employeeInfo.getEmployeeId(), indicator.getEvaluationMetric(), awd)));
                                indicatorDetail.setIndicatorScore(employeeScore.getKeyTaskScore());
                                break;
                            case "114":
                                employeeScore.setPerformanceScore(BigDecimal.valueOf(getPerformanceScore(employeeInfo.getEmployeeId(), indicator.getEvaluationMetric(), awd)));
                                indicatorDetail.setIndicatorScore(employeeScore.getPerformanceScore());
                                break;
                            case "115":
                                employeeScore.setGoalTaskScore(BigDecimal.valueOf(getGoalTaskScore(employeeInfo.getEmployeeId(), indicator.getEvaluationMetric(), awd)));
                                indicatorDetail.setIndicatorScore(employeeScore.getGoalTaskScore());
                                break;
                            case "116":
                                employeeScore.setAnnualWorkingDaysScore(BigDecimal.valueOf(getAnnualWorkingDaysScore(employeeInfo.getEmployeeId(), indicator.getEvaluationMetric(), awd)));
                                indicatorDetail.setIndicatorScore(employeeScore.getAnnualWorkingDaysScore());
                                break;
                            case "117":
                                employeeScore.setPaperScore(BigDecimal.valueOf(getPaperScore(employeeInfo.getEmployeeId(), indicator.getEvaluationMetric(), awd)));
                                indicatorDetail.setIndicatorScore(employeeScore.getPaperScore());
                                break;
                            case "118":
                                employeeScore.setInnovationScore(BigDecimal.valueOf(getInnovationScore(employeeInfo.getEmployeeId(), indicator.getEvaluationMetric(), awd)));
                                indicatorDetail.setIndicatorScore(employeeScore.getInnovationScore());
                                break;

                            case "184":
                                employeeScore.setInidcatorOneScore(BigDecimal.valueOf(getInidcatorOneScore(employeeInfo.getEmployeeId(), indicator.getEvaluationMetric(), awd)));
                                indicatorDetail.setIndicatorScore(employeeScore.getInidcatorOneScore());
                                break;
                            case "185":
                                employeeScore.setInidcatorTowScore(BigDecimal.valueOf(getInidcatorTowScore(employeeInfo.getEmployeeId(), indicator.getEvaluationMetric(), awd)));
                                indicatorDetail.setIndicatorScore(employeeScore.getInidcatorTowScore());
                                break;
                            case "186":
                                employeeScore.setInidcatorThreeScore(BigDecimal.valueOf(getInidcatorThreeScore(employeeInfo.getEmployeeId(), indicator.getEvaluationMetric(), awd)));
                                indicatorDetail.setIndicatorScore(employeeScore.getInidcatorThreeScore());
                                break;
                            case "187":
                                employeeScore.setInidcatorFourScore(BigDecimal.valueOf(getInidcatorFourScore(employeeInfo.getEmployeeId(), indicator.getEvaluationMetric(), awd)));
                                indicatorDetail.setIndicatorScore(employeeScore.getInidcatorFourScore());
                                break;
                            case "188":
                                employeeScore.setInidcatorFiveScore(BigDecimal.valueOf(getInidcatorFiveScore(employeeInfo.getEmployeeId(), indicator.getEvaluationMetric(), awd)));
                                indicatorDetail.setIndicatorScore(employeeScore.getInidcatorFiveScore());
                                break;
                            case "189":
                                employeeScore.setInidcatorSixScore(BigDecimal.valueOf(getInidcatorSixScore(employeeInfo.getEmployeeId(), indicator.getEvaluationMetric(), awd)));
                                indicatorDetail.setIndicatorScore(employeeScore.getInidcatorSixScore());
                                break;
                        }

                        IndicatorDetail es = new IndicatorDetail();
                        es.setEmployeeId(indicatorDetail.getEmployeeId());
                        es.setAwardYear(indicatorDetail.getAwardYear());
                        es.setIndicatorType(indicatorDetail.getIndicatorType());
                        List<IndicatorDetail> selectIndicatorDetailList = indicatorDetailMapper.selectIndicatorDetailList(es);
                        if (selectIndicatorDetailList.isEmpty()) {
                            indicatorDetail.setCreateTime(new Date());
                            indicatorDetailMapper.insertIndicatorDetail(indicatorDetail);
                        } else {
                            indicatorDetail.setId(selectIndicatorDetailList.get(0).getId());
                            indicatorDetail.setUpdateTime(new Date());
                            indicatorDetailMapper.updateIndicatorDetail(indicatorDetail);
                        }

                    }catch (Exception e){
                        e.printStackTrace();
                        logger.error("Failed to rerun data for year {}", awd, e);
                    }
                }

                calculateScores(employeeScore);
                getRatingStar(employeeScore);

                EmployeeScore es = new EmployeeScore();
                es.setEmployeeId(employeeScore.getEmployeeId());
                es.setAwardYear(awd);
                List<EmployeeScore>list = employeeScoreMapper.selectEmployeeScoreList(es);
                if(list.isEmpty()){
                    employeeScore.setCreateTime(new Date());
                    employeeScoreMapper.insertEmployeeScore(employeeScore);
                }else{
                    employeeScore.setId(list.get(0).getId());
                    employeeScore.setUpdateTime(DateUtils.getNowDate());
                    employeeScoreMapper.updateEmployeeScore(employeeScore);
                }
            }
        } catch (Exception e) {
            logger.error("Failed to rerun data for year {}", awd, e);
            throw new RuntimeException("Failed to rerun data for year " + awd, e);
        }
    }

    private double getInidcatorSixScore(String employeeId, String evaluationMetric, Date awd) {
        Double trainingScore = 0d;

        IndicatorSix et = new IndicatorSix();
        et.setEmployeeId(employeeId);
        et.setAwardYear(awd);

        List<IndicatorSix>employeeTrainingList = indicatorSixMapper.selectIndicatorSixList(et);

        if(!employeeTrainingList.isEmpty()){
            List<SysDictData>trainingContributioList = getDictData(Long.parseLong(evaluationMetric));
            for (IndicatorSix trainingRecord:employeeTrainingList){

                for(SysDictData sysDictData:trainingContributioList){
                    if(sysDictData.getDictLabel().equals(trainingRecord.getIndicatorSix())){
                        trainingScore += Double.parseDouble(sysDictData.getDictValue());
                    }
                }
            }
        }

        return trainingScore;
    }

    private double getInidcatorFiveScore(String employeeId, String evaluationMetric, Date awd) {
        Double trainingScore = 0d;

        IndicatorFive et = new IndicatorFive();
        et.setEmployeeId(employeeId);
        et.setAwardYear(awd);

        List<IndicatorFive>employeeTrainingList = indicatorFiveMapper.selectIndicatorFiveList(et);

        if(!employeeTrainingList.isEmpty()){
            List<SysDictData>trainingContributioList = getDictData(Long.parseLong(evaluationMetric));
            for (IndicatorFive trainingRecord:employeeTrainingList){

                for(SysDictData sysDictData:trainingContributioList){
                    if(sysDictData.getDictLabel().equals(trainingRecord.getIndicatorFive())){
                        trainingScore += Double.parseDouble(sysDictData.getDictValue());
                    }
                }
            }
        }

        return trainingScore;
    }

    private double getInidcatorFourScore(String employeeId, String evaluationMetric, Date awd) {
        Double trainingScore = 0d;

        IndicatorFour et = new IndicatorFour();
        et.setEmployeeId(employeeId);
        et.setAwardYear(awd);

        List<IndicatorFour>employeeTrainingList = indicatorFourMapper.selectIndicatorFourList(et);

        if(!employeeTrainingList.isEmpty()){
            List<SysDictData>trainingContributioList = getDictData(Long.parseLong(evaluationMetric));
            for (IndicatorFour trainingRecord:employeeTrainingList){

                for(SysDictData sysDictData:trainingContributioList){

                    if(sysDictData.getDictLabel().equals(trainingRecord.getIndicatorFour())){
                        trainingScore += Double.parseDouble(sysDictData.getDictValue());
                    }
                }
            }
        }

        return trainingScore;
    }

    private double getInidcatorThreeScore(String employeeId, String evaluationMetric, Date awd) {
        Double trainingScore = 0d;

        IndicatorThree et = new IndicatorThree();
        et.setEmployeeId(employeeId);
        et.setAwardYear(awd);

        List<IndicatorThree>employeeTrainingList = indicatorThreeMapper.selectIndicatorThreeList(et);

        if(!employeeTrainingList.isEmpty()){
            List<SysDictData>trainingContributioList = getDictData(Long.parseLong(evaluationMetric));
            for (IndicatorThree trainingRecord:employeeTrainingList){

                for(SysDictData sysDictData:trainingContributioList){

                    if(sysDictData.getDictLabel().equals(trainingRecord.getIndicatorThree())){
                        trainingScore += Double.parseDouble(sysDictData.getDictValue());
                    }
                }
            }
        }

        return trainingScore;
    }

    private double getInidcatorTowScore(String employeeId, String evaluationMetric, Date awd) {
        Double trainingScore = 0d;

        IndicatorTow et = new IndicatorTow();
        et.setEmployeeId(employeeId);
        et.setAwardYear(awd);

        List<IndicatorTow>employeeTrainingList = indicatorTowMapper.selectIndicatorTowList(et);

        if(!employeeTrainingList.isEmpty()){
            List<SysDictData>trainingContributioList = getDictData(Long.parseLong(evaluationMetric));
            for (IndicatorTow trainingRecord:employeeTrainingList){

                double pre = 0;
                for(SysDictData sysDictData:trainingContributioList){

                    if(sysDictData.getDictLabel().equals(trainingRecord.getIndicatorTow())){
                        trainingScore += Double.parseDouble(sysDictData.getDictValue());
                    }
                }
            }
        }



        return trainingScore;
    }

    private double getInidcatorOneScore(String employeeId, String evaluationMetric, Date awd) {
        Double trainingScore = 0d;

        IndicatorOne et = new IndicatorOne();
        et.setEmployeeId(employeeId);
        et.setAwardYear(awd);

        List<IndicatorOne>employeeTrainingList = indicatorOneMapper.selectIndicatorOneList(et);

        if(!employeeTrainingList.isEmpty()){
            List<SysDictData>trainingContributioList = getDictData(Long.parseLong(evaluationMetric));
            for (IndicatorOne trainingRecord:employeeTrainingList){

                for(SysDictData sysDictData:trainingContributioList){

                    if(sysDictData.getDictLabel().equals(trainingRecord.getIndicatorOne())){
                        trainingScore += Double.parseDouble(sysDictData.getDictValue());
                    }
                }
            }
        }

        return trainingScore;
    }

    private void calculateScores(EmployeeScore employeeScore) {
        BigDecimal willingnessToImproveScore = employeeScore.getTitleLevelScore()
                .add(employeeScore.getQualificationScore())
                .add(employeeScore.getAwardScore())
                .add(employeeScore.getTrainingContributionScore())
                .add(employeeScore.getTrainingParticipationScore())
                        .add(employeeScore.getInidcatorOneScore())
                                .add(employeeScore.getInidcatorTowScore())
                                        .add(employeeScore.getInidcatorThreeScore());
        employeeScore.setWillingnessToImproveScore(willingnessToImproveScore);

        BigDecimal performanceScore = employeeScore.getWorkPracticeScore()
                .add(employeeScore.getJobExperienceScore())
                .add(employeeScore.getKeyTaskScore())
                .add(employeeScore.getPerformanceScore())
                .add(employeeScore.getGoalTaskScore())
                .add(employeeScore.getAnnualWorkingDaysScore())
                .add(employeeScore.getPaperScore())
                .add(employeeScore.getInnovationScore())
                .add(employeeScore.getInidcatorFourScore())
                .add(employeeScore.getInidcatorFiveScore())
                .add(employeeScore.getInidcatorSixScore());
        employeeScore.setPerformanceAbilityScore(performanceScore);

        Double centralizedTrainingHours = 0D;
        String cet = employeeTrainingMapper.selectByTrainingForm(employeeScore.getEmployeeId(), "集中培训", employeeScore.getAwardYear());
        if(null != cet){centralizedTrainingHours = Double.parseDouble(cet);}
        employeeScore.setCentralizedTrainingHours(BigDecimal.valueOf(centralizedTrainingHours));

        Double onlineSelfStudyHours = 0d;
        String osls = employeeTrainingMapper.selectByTrainingForm(employeeScore.getEmployeeId(), "网络自学", employeeScore.getAwardYear());
        if(null != osls){onlineSelfStudyHours = Double.parseDouble(osls);}
        employeeScore.setOnlineSelfStudyHours(BigDecimal.valueOf(onlineSelfStudyHours));
    }

    /**
     * 高效学习者：履职能力≥50，培训意愿≥50;  用“五颗星”表示
     *
     *       潜力新星：履职能力＜50，培训意愿≥50;  用“三颗星”表示
     *
     *       待提升人员：履职能力＜50，培训意愿＜50;  用“两颗星”表示
     *
     *       资深专家：履职能力≥50，培训意愿＜50;  用“四颗星”表示
     * @param employeeScore
     */
    public void getRatingStar(EmployeeScore employeeScore){

        //t_employee_classification_training_suggestions
        List<EmployeeClassificationTrainingSuggestions> list = employeeClassificationTrainingSuggestionsMapper.selectEmployeeSuggestionsList(new EmployeeClassificationTrainingSuggestions());
        for (EmployeeClassificationTrainingSuggestions employeeClassificationTrainingSuggestions : list){

            if(employeeClassificationTrainingSuggestions.getStarRating() ==2 && employeeScore.getWillingnessToImproveScore().compareTo(new BigDecimal(employeeClassificationTrainingSuggestions.getImprovementWill()))<0
                    && employeeScore.getPerformanceAbilityScore().compareTo(new BigDecimal(employeeClassificationTrainingSuggestions.getJobPerformance()))<0 ){

                employeeScore.setRatingStar(2L);
                employeeScore.setRatingStarName("二星级");
                employeeScore.setLevelName(employeeClassificationTrainingSuggestions.getQuadrant());
                employeeScore.setLevelId(employeeClassificationTrainingSuggestions.getId());
            }

            if(employeeClassificationTrainingSuggestions.getStarRating() ==3
                    && employeeScore.getWillingnessToImproveScore().compareTo(new BigDecimal(employeeClassificationTrainingSuggestions.getImprovementWill()))>=0
            && employeeScore.getPerformanceAbilityScore().compareTo(new BigDecimal(employeeClassificationTrainingSuggestions.getJobPerformance()))<0 ){

                employeeScore.setRatingStar(3L);
                employeeScore.setRatingStarName("三星级");
                employeeScore.setLevelName(employeeClassificationTrainingSuggestions.getQuadrant());
                employeeScore.setLevelId(employeeClassificationTrainingSuggestions.getId());
            }

            if(employeeClassificationTrainingSuggestions.getStarRating() ==4 && employeeScore.getWillingnessToImproveScore().compareTo(new BigDecimal(employeeClassificationTrainingSuggestions.getImprovementWill()))<0
            && employeeScore.getPerformanceAbilityScore().compareTo(new BigDecimal(employeeClassificationTrainingSuggestions.getJobPerformance()))>=0 ){

                employeeScore.setRatingStar(4L);
                employeeScore.setRatingStarName("四星级");
                employeeScore.setLevelName(employeeClassificationTrainingSuggestions.getQuadrant());
                employeeScore.setLevelId(employeeClassificationTrainingSuggestions.getId());
            }

            if(employeeClassificationTrainingSuggestions.getStarRating() ==5
                    && employeeScore.getWillingnessToImproveScore().compareTo(new BigDecimal(employeeClassificationTrainingSuggestions.getImprovementWill()))>=0
                    && employeeScore.getPerformanceAbilityScore().compareTo(new BigDecimal(employeeClassificationTrainingSuggestions.getJobPerformance()))>=0 ){

                employeeScore.setRatingStar(5L);
                employeeScore.setRatingStarName("五星级");
                employeeScore.setLevelName(employeeClassificationTrainingSuggestions.getQuadrant());
                employeeScore.setLevelId(employeeClassificationTrainingSuggestions.getId());
            }
        }
    }

    private double getPaperScore(String employeeId, String evaluationMetric,Date awd) {

        //论文论著 t_papers_and_books
        Double trainingScore = 0d;
        //t_task_info
        PapersAndBooks et = new PapersAndBooks();
        et.setEmployeeId(employeeId);
        et.setAwardYear(awd);

        Double weight1 = getWeight(Long.parseLong(evaluationMetric));

        List<PapersAndBooks>employeeTrainingList = papersAndBooksMapper.selectPapersAndBooksList(et);
        List<SysDictData>trainingContributioList = getDictData(Long.parseLong(evaluationMetric));
        for (PapersAndBooks trainingRecord:employeeTrainingList){

            //author_rank
            Long authorRank = trainingRecord.getAuthorRank();
            for(SysDictData sysDictData:trainingContributioList){

                //DictLabel
                String dictLabel = sysDictData.getDictLabel();

                if(authorRank == Long.parseLong(dictLabel)){
                    trainingScore += Double.parseDouble(sysDictData.getDictValue());
                }

            }
        }

        Double result1 = trainingScore>weight1?weight1:trainingScore;

        return result1;
    }

    private double getInnovationScore(String employeeId, String evaluationMetric,Date awd) {

        //成果 t_achievement_awards
        Double trainingScore = 0d;
        //t_task_info
        AchievementAwards et = new AchievementAwards();
        et.setEmployeeId(employeeId);
        et.setAwardYear(awd);

        Double weight1 = getWeight(Long.parseLong(evaluationMetric));

        List<AchievementAwards>employeeTrainingList = achievementAwardsMapper.selectAchievementAwardsList(et);
        List<SysDictData>trainingContributioList = getDictData(Long.parseLong(evaluationMetric));
        for (AchievementAwards trainingRecord:employeeTrainingList){

            //achievement_level
            String achievementLevel = trainingRecord.getAchievementLevel();
            word:for(SysDictData sysDictData:trainingContributioList){

                //DictLabel
                String dictLabel = sysDictData.getDictLabel();
                String[]strings = dictLabel.split("-");
                //判断strings 元素都包含在achievementLevel 中时才会获取sysDictData.getDictValue()值
                for (String string:strings){
                    if(achievementLevel.indexOf(string) == -1){
                        continue word;
                    }
                }

                trainingScore += Double.parseDouble(sysDictData.getDictValue());

            }
        }

        Double result1 = trainingScore>weight1?weight1:trainingScore;

        return result1;
    }

    private double getAnnualWorkingDaysScore(String employeeId, String evaluationMetric,Date awd) {

        //全年出班天数  t_annual_work_days
        Double trainingScore = 0d;
        //t_task_info
        AnnualPlanWork et = new AnnualPlanWork();
        et.setEmployeeId(employeeId);
        et.setAwardYear(awd);

        Double weight1 = getWeight(Long.parseLong(evaluationMetric));

        List<AnnualPlanWork>employeeTrainingList = annualPlanWorkMapper.selectAnnualPlanWorkList(et);
        List<SysDictData>trainingContributioList = getDictData(Long.parseLong(evaluationMetric));
        for (AnnualPlanWork trainingRecord:employeeTrainingList){

            //full_year_duty_days_score
            BigDecimal performanceGrade = trainingRecord.getFullYearDutyDaysScore();

            for(SysDictData sysDictData:trainingContributioList){

                //DictLabel
                String dictLabel = sysDictData.getDictLabel();
                String[]strings = dictLabel.split("-");
                int performanceGradeInt = performanceGrade.multiply(new BigDecimal(100)).intValue();

                if(performanceGradeInt>=Integer.parseInt(strings[0]) && performanceGradeInt<Integer.parseInt(strings[1])){
                    trainingScore = Double.parseDouble(sysDictData.getDictValue());
                }

            }
        }

        Double result1 = trainingScore>weight1?weight1:trainingScore;

        return result1;
    }

    private double getGoalTaskScore(String employeeId, String evaluationMetric,Date awd) {
        //工作目标任务  t_annual_plan_work
        Double trainingScore = 0d;
        //t_task_info
        AnnualPlanWork et = new AnnualPlanWork();
        et.setEmployeeId(employeeId);
        et.setAwardYear(awd);

        Double weight1 = getWeight(Long.parseLong(evaluationMetric));

        List<AnnualPlanWork>employeeTrainingList = annualPlanWorkMapper.selectAnnualPlanWorkList(et);
        List<SysDictData>trainingContributioList = getDictData(Long.parseLong(evaluationMetric));
        for (AnnualPlanWork trainingRecord:employeeTrainingList){

            //completion_percentage
           BigDecimal performanceGrade = trainingRecord.getCompletionPercentage();

            for(SysDictData sysDictData:trainingContributioList){

                //DictLabel
                String dictLabel = sysDictData.getDictLabel();
                String[]strings = dictLabel.split("-");
                int performanceGradeInt = performanceGrade.multiply(new BigDecimal(100)).intValue();

                if(performanceGradeInt>=Integer.parseInt(strings[0]) && performanceGradeInt<Integer.parseInt(strings[1])){
                    trainingScore = Double.parseDouble(sysDictData.getDictValue());
                }

            }
        }

        Double result1 = trainingScore>weight1?weight1:trainingScore;

        return result1;
    }

    private double getPerformanceScore(String employeeId, String evaluationMetric,Date awd) {

        //t_employee_performance 年度绩效

        Double trainingScore = 0d;
        //t_task_info
        EmployeePerformance et = new EmployeePerformance();
        et.setEmployeeId(employeeId);

        et.setAwardYear(awd);

        Double weight1 = getWeight(Long.parseLong(evaluationMetric));

        List<EmployeePerformance>employeeTrainingList = employeePerformanceMapper.selectEmployeePerformanceList(et);
        List<SysDictData>trainingContributioList = getDictData(Long.parseLong(evaluationMetric));
        for (EmployeePerformance trainingRecord:employeeTrainingList){

            //performance_grade
            String performanceGrade = trainingRecord.getPerformanceGrade()==null?"":trainingRecord.getPerformanceGrade();

            for(SysDictData sysDictData:trainingContributioList){
                //training_level
                if(performanceGrade.indexOf(sysDictData.getDictLabel()) != -1){
                    trainingScore += Double.parseDouble(sysDictData.getDictValue());
                }

            }
        }

        Double result1 = trainingScore>weight1?weight1:trainingScore;

        return result1;
    }

    private double getKeyTaskScore(String employeeId, String evaluationMetric,Date awd) {

        Double trainingScore = 0d;
        //t_task_info
        AnnualPlanWork et = new AnnualPlanWork();
        et.setEmployeeId(employeeId);
        et.setAwardYear(awd);

        Double weight1 = getWeight(Long.parseLong(evaluationMetric));

        List<AnnualPlanWork>employeeTrainingList = annualPlanWorkMapper.selectAnnualPlanWorkList(et);
        List<SysDictData>trainingContributioList = getDictData(Long.parseLong(evaluationMetric));
        for (AnnualPlanWork trainingRecord:employeeTrainingList){

            //key_tasks_score
            BigDecimal performanceGrade = trainingRecord.getKeyTasksScore();

            for(SysDictData sysDictData:trainingContributioList){

                //DictLabel
                String dictLabel = sysDictData.getDictLabel();
                String[]strings = dictLabel.split("-");
                int performanceGradeInt = performanceGrade.multiply(new BigDecimal(100)).intValue();

                if(performanceGradeInt>=Integer.parseInt(strings[0]) && performanceGradeInt<Integer.parseInt(strings[1])){
                    trainingScore = Double.parseDouble(sysDictData.getDictValue());
                }

            }
        }

        Double result1 = trainingScore>weight1?weight1:trainingScore;

        return result1;

    }

    /**
     * 员工基本信息：先判断岗位大类为技能类再匹配岗位名称 岗位大类字段和岗位名称字段最后任职时间字段和当前时间对比为年限
     * @param employee
     * @param evaluationMetric
     * @return
     */
    public double getJobExperienceScore(EmployeeInfo employee, String evaluationMetric,Date awd) {
        Double result = 0D;

        // 检查 employee 和 evaluationMetric 是否为空
        if (employee == null || evaluationMetric == null) {
            return result;
        }

        // position_category_minor
        if ("技能类".equals(employee.getPositionCategoryMajor())) {
            // 岗位名称
            String positionName = employee.getPositionName();
            // 最后任职时间 appointment_date
            Date lastPostingTime = employee.getAppointmentDate();

            // 检查 lastPostingTime 是否为空
            if (lastPostingTime == null) {
                return result;
            }

            // 计算任职年限

            Calendar calendar = Calendar.getInstance();
            calendar.setTime(awd);

            Calendar cal = Calendar.getInstance();
            cal.setTime(new Date());
            cal.set(Calendar.YEAR,calendar.get(Calendar.YEAR));

            long currentTimeMillis = cal.getTimeInMillis();
            long lastPostingTimeMillis = lastPostingTime.getTime();
            long durationInMillis = currentTimeMillis - lastPostingTimeMillis;
            long yearsOfExperience = TimeUnit.MILLISECONDS.toDays(durationInMillis) / 365;

            // 获取评分标准列表
            List<SysDictData> trainingContributioList = getDictData(Long.parseLong(evaluationMetric));

            // 根据任职年限查找对应的评分标准
            for (SysDictData dictData : trainingContributioList) {
                String dictLabel = dictData.getDictLabel();
                if (dictLabel != null) {
                    if (dictLabel.contains(positionName+","+"0-1年") && yearsOfExperience >= 0 && yearsOfExperience < 1) {
                        result = parseDouble(dictData.getDictValue());
                        break;
                    } else if (dictLabel.contains(positionName+","+"1-2年") && yearsOfExperience >= 1 && yearsOfExperience < 2) {
                        result = parseDouble(dictData.getDictValue());
                        break;
                    } else if (dictLabel.contains(positionName+","+"2-4年") && yearsOfExperience >= 2 && yearsOfExperience < 4) {
                        result = parseDouble(dictData.getDictValue());
                        break;
                    } else if (dictLabel.contains(positionName+","+"4年以上") && yearsOfExperience >= 4) {
                        result = parseDouble(dictData.getDictValue());
                        break;
                    }
                }
            }
        }

        return result;
    }

    private Double parseDouble(String value) {
        try {
            return Double.parseDouble(value);
        } catch (NumberFormatException e) {
            // 处理无法解析为 Double 的情况
            return 0D;
        }
    }


    private double getTrainingContributionScore(String employeeId, String evaluationMetric,Date awd) {

        //培训贡献
        Double trainingScore = 0d;
        //t_employee_training
        TrainingRecord et = new TrainingRecord();
        et.setEmployeeId(employeeId);

        et.setAwardYear(awd);

        Double weight1 = getWeight(Long.parseLong(evaluationMetric));

        List<TrainingRecord>employeeTrainingList = trainingRecordMapper.selectTrainingRecordList(et);
        List<SysDictData>trainingContributioList = getDictData(Long.parseLong(evaluationMetric));
        for (TrainingRecord trainingRecord:employeeTrainingList){
            for(SysDictData sysDictData:trainingContributioList){
                //training_level
                if(trainingRecord.getTrainingLevel().indexOf(sysDictData.getDictLabel()) != -1){
                    trainingScore += Double.parseDouble(sysDictData.getDictValue());
                }

            }
        }

        Double result1 = trainingScore>weight1?weight1:trainingScore;
        
        return result1;
    }

    private double getAwardScore(String employeeId, String evaluationMetric,Date awd) {

        //表彰奖励 t_employee_awards_info
        Double awardScore = 0d;
        EmployeeAwardsInfo  em = new EmployeeAwardsInfo();
        em.setEmployeeId(employeeId);
        em.setAwardYear(awd);

        Double weight = getWeight(Long.parseLong(evaluationMetric));

        List<SysDictData>awardScoreList = getDictData(Long.parseLong(evaluationMetric));

        List<EmployeeAwardsInfo>list2 = employeeAwardsInfoMapper.selectEmployeeAwardsInfoList(em);
        info:for (EmployeeAwardsInfo employeeAwardsInfo:list2){
            dict:for(SysDictData sysDictData:awardScoreList){

                if(employeeAwardsInfo.getHonorTitle() == null || employeeAwardsInfo.getHonorTitle().equals("")){
                    continue info;
                }
                //honor_level
                if(employeeAwardsInfo.getHonorLevel().indexOf(sysDictData.getDictLabel()) != -1){
                    awardScore += Double.parseDouble(sysDictData.getDictValue());
                    break;
                }else if("其他".equals(sysDictData.getDictLabel())){
                    awardScore += Double.parseDouble(sysDictData.getDictValue());
                    break;
                }

            }
        }

        Double result = awardScore>weight?weight:awardScore;
        
        return result;
    }

    private double getQualificationScore(String skillLevel, String evaluationMetric) {

        Double titleLevelScore = 0D;
        List<SysDictData>qualificationScoreList = getDictData(Long.parseLong(evaluationMetric));
        //获取
        for (SysDictData sysDictData:qualificationScoreList){
            //skill_level
            if(sysDictData.getDictLabel().equals(skillLevel)){
                titleLevelScore = Double.parseDouble(sysDictData.getDictValue());
            }
        }
        
        return titleLevelScore;
    }

    private double getTitleLevelScore(String professionalQualificationLevel, String evaluationMetric) {

        Double titleLeve = 0D;
        List<SysDictData>list1 = getDictData(Long.parseLong(evaluationMetric));
        //获取
        for (SysDictData sysDictData:list1){
            //professional_qualification_level
            if(sysDictData.getDictLabel().equals(professionalQualificationLevel)){
                titleLeve = Double.parseDouble(sysDictData.getDictValue());
            }
        }
        
        return titleLeve;
    }

    private double getWorkPracticeScore(String employeeId, String evaluationMetric,Date awd) {

        //工作目标任务  t_annual_plan_work
        Double trainingScore = 0d;
        //t_task_info
        AnnualPlanWork et = new AnnualPlanWork();
        et.setEmployeeId(employeeId);
        et.setAwardYear(awd);

        Double weight1 = getWeight(Long.parseLong(evaluationMetric));

        List<AnnualPlanWork>employeeTrainingList = annualPlanWorkMapper.selectAnnualPlanWorkList(et);
        List<SysDictData>trainingContributioList = getDictData(Long.parseLong(evaluationMetric));
        for (AnnualPlanWork trainingRecord:employeeTrainingList){

            //work_practice_score
            BigDecimal performanceGrade = trainingRecord.getWorkPracticeScore();

            for(SysDictData sysDictData:trainingContributioList){

                //DictLabel
                String dictLabel = sysDictData.getDictLabel();
                String[]strings = dictLabel.split("-");
                int performanceGradeInt = performanceGrade.multiply(new BigDecimal(100)).intValue();

                if(performanceGradeInt>=Integer.parseInt(strings[0]) && performanceGradeInt<Integer.parseInt(strings[1])){
                    trainingScore = Double.parseDouble(sysDictData.getDictValue());
                }

            }
        }

        Double result1 = trainingScore>weight1?weight1:trainingScore;

        return result1;
    }

    public double getTrainingParticipationScore(String employeeId,String evaluationMetric,Date awd) {

        //培训贡献
        Double trainingScore = 0d;
        //t_employee_training
        EmployeeTraining et = new EmployeeTraining();
        et.setEmployeeId(employeeId);

        et.setAwardYear(awd);

        Double weight1 = getWeight(Long.parseLong(evaluationMetric));
        //t_employee_training
        List<EmployeeTraining>employeeTrainingList = employeeTrainingMapper.selectEmployeeTrainingList(et);
        List<SysDictData>trainingContributioList = getDictData(Long.parseLong(evaluationMetric));
        for (EmployeeTraining trainingRecord:employeeTrainingList){
            for(SysDictData sysDictData:trainingContributioList){

                long train= trainingRecord.getTrainingHours()==null?0:trainingRecord.getTrainingHours();
                //training_hours
                trainingScore += Double.parseDouble(sysDictData.getDictValue()) * train;

            }
        }

        Double result1 = trainingScore>weight1?weight1:trainingScore;

        return result1;
    }

    public List<SysDictData>getDictData(Long id){

        SysDictData sysDictData = dictDataService.selectDictDataById(id);
        // 获取类型
        String dictType = sysDictData.getRemark();
        SysDictType sysDictType = dictTypeService.selectDictTypeById(Long.parseLong(dictType));
        // 获取模版数据
        List<SysDictData> datas = dictTypeService.selectDictDataByType(sysDictType.getDictType());

        return datas;
    }

    public double getWeight(Long id) {

        SysDictData sysDictData = dictDataService.selectDictDataById(id);
        return Double.parseDouble(sysDictData.getDictValue());
    }

    @Override
    public void reRunAll() {

        indicatorDetailMapper.clearTable();

        employeeScoreMapper.clearTable();

        //获取所有的年份
        List<Date> years = employeeScoreMapper.getAllIndexYears(new EmployeeScore());
        for (Date awd:years){
            reRun(awd);
        }
    }

    @Override
    public List<Date> getYearList() {

        List<Date> years = employeeScoreMapper.getAllIndexYears(new EmployeeScore());
        return years;
    }

    @Override
    public void clear(Date awd) {
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy");

            System.out.println(awd);
            achievementAwardsMapper.clearTableYear(awd);
            annualPlanWorkMapper.clearTableYear(awd);
            taskInfoMapper.clearTableYear(awd);
            trainingRecordMapper.clearTableYear(awd);
            workTicketInfoMapper.clearTableYear(awd);
            indicatorDetailMapper.clearTableYear(awd);
            employeePerformanceMapper.clearTableYear(awd);
            //employeeInfoMapper.clearTableYear(awd);
            annualWorkDaysMapper.clearTableYear(awd);
            employeeAwardsInfoMapper.clearTableYear(awd);
            employeeTrainingMapper.clearTableYear(awd);
            papersAndBooksMapper.clearTableYear(awd);
            employeeScoreMapper.clearTableYear(awd);
        } catch (Exception e) {
            logger.error("Failed to clear tables", e);
            throw new RuntimeException("Failed to clear tables", e);
        }
    }
}
